<?php

namespace App\Services\Bank;

use Illuminate\Support\Manager;
use App\Services\Bank\BankOfHangzhou\BankOfHangzhouClient;
use App\Services\Bank\BankOfHangzhou\BankOfHangzhouConfig;
use App\Services\Bank\BankOfHangzhou\BankOfHangzhouService;

class BankServiceManager extends Manager implements BankServiceInterface
{
    /**
     * 获取默认驱动名称
     *
     * @return string
     */
    public function getDefaultDriver()
    {
        return $this->config->get('bank.default', 'BankOfHangzhou');
    }

    /**
     * 创建杭州银行驱动
     *
     * @return BankOfHangzhouService
     */
    public function createBankOfHangzhouDriver(): BankOfHangzhouService
    {
        $config = $this->config->get('bank.banks.BankOfHangzhou');

        $bankConfig = new BankOfHangzhouConfig(
            $config['erp_sys_code'],
            $config['cust_no'],
            [
                'timeout' => $config['timeout'] ?? 30,
                'charset' => $config['charset'] ?? 'UTF-8',
                'message_type' => $config['message_type'] ?? '01',
                'with_header' => $config['with_header'] ?? false,
            ]
        );

        $client = new BankOfHangzhouClient($bankConfig);
        return new BankOfHangzhouService($client);
    }

    /**
     * 代理方法 - 联行号增量同步
     */
    public function syncBankNumbers(string $queryDate): array
    {
        return $this->driver()->syncBankNumbers($queryDate);
    }

    /**
     * 代理方法 - 联行号查询
     */
    public function queryBankNumbers(string $bankName, ?string $bankTypeName = null, ?string $isPreciseQuery = '0'): array
    {
        return $this->driver()->queryBankNumbers($bankName, $bankTypeName, $isPreciseQuery);
    }

    /**
     * 代理方法 - 余额查询
     */
    public function queryBalance(string $bankAcc): array
    {
        return $this->driver()->queryBalance($bankAcc);
    }

    /**
     * 代理方法 - 批量代发
     */
    public function batchPay(string $erpBatchNo, string $wageTitle, string $busiType, array $payDetails, array $options = []): array
    {
        return $this->driver()->batchPay($erpBatchNo, $wageTitle, $busiType, $payDetails, $options);
    }

    /**
     * 代理方法 - 代发结果查询
     */
    public function queryPayResult(?string $erpBatchNo = null, ?string $startDate = null, ?string $endDate = null): array
    {
        return $this->driver()->queryPayResult($erpBatchNo, $startDate, $endDate);
    }

    /**
     * 代理方法 - 回单批量申请
     */
    public function batchApplyReceipt(string $compFlowNo, string $beginDate, string $endDate, array $bankAccounts): array
    {
        return $this->driver()->batchApplyReceipt($compFlowNo, $beginDate, $endDate, $bankAccounts);
    }

    /**
     * 代理方法 - 单笔回单下载
     */
    public function downloadSingleReceipt(string $receiptNo): array
    {
        return $this->driver()->downloadSingleReceipt($receiptNo);
    }

    /**
     * 代理方法 - 当日明细查询
     */
    public function queryDailyDetails(string $bankAcc, ?float $queryAmtBegin = null, ?float $queryAmtEnd = null, ?string $queryCdSign = null, ?string $expandFields = null): array
    {
        return $this->driver()->queryDailyDetails($bankAcc, $queryAmtBegin, $queryAmtEnd, $queryCdSign, $expandFields);
    }

    /**
     * 代理方法 - 历史明细查询
     */
    public function queryHistoryDetails(string $bankAcc, string $queryDateBegin, string $queryDateEnd, ?float $queryAmtBegin = null, ?float $queryAmtEnd = null, ?string $queryCdSign = null, ?string $expandFields = null): array
    {
        return $this->driver()->queryHistoryDetails($bankAcc, $queryDateBegin, $queryDateEnd, $queryAmtBegin, $queryAmtEnd, $queryCdSign, $expandFields);
    }

    /**
     * 代理方法 - 验证批量代发明细数据格式
     */
    public function validatePayDetails(array $payDetails): array
    {
        return $this->driver()->validatePayDetails($payDetails);
    }

    /**
     * 代理方法 - 获取支付状态
     */
    public function getPaymentStatus(array $result): string
    {
        return $this->driver()->getPaymentStatus($result);
    }

    /**
     * 代理方法 - 格式化日期
     */
    public function formatDate($date): string
    {
        return $this->driver()->formatDate($date);
    }

    /**
     * 代理方法 - 同步银行明细到数据库
     */
    public function syncDetailsToDatabase(string $bankAcc, int $days = 1, ?string $syncBatchId = null): array
    {
        return $this->driver()->syncDetailsToDatabase($bankAcc, $days, $syncBatchId);
    }

    /**
     * 代理方法 - 获取同步统计信息
     */
    public function getSyncStats(?string $syncBatchId = null): array
    {
        return $this->driver()->getSyncStats($syncBatchId);
    }

    /**
     * 代理方法 - 执行充值匹配算法
     */
    public function runRechargeMatching(array $options = []): array
    {
        return $this->driver()->runRechargeMatching($options);
    }

    /**
     * 代理方法 - 手动确认匹配
     */
    public function confirmMatch(int $rechargeId, int $bankDetailId, ?int $operatorId = null): array
    {
        return $this->driver()->confirmMatch($rechargeId, $bankDetailId, $operatorId);
    }

    /**
     * 代理方法 - 取消匹配
     */
    public function cancelMatch(int $rechargeId, ?int $operatorId = null): array
    {
        return $this->driver()->cancelMatch($rechargeId, $operatorId);
    }

    /**
     * 使用指定银行
     *
     * @param string $bankName
     * @return BankServiceInterface
     */
    public function bank(string $bankName): BankServiceInterface
    {
        return $this->driver($bankName);
    }

    /**
     * 获取所有可用银行
     *
     * @return array
     */
    public function getAvailableBanks(): array
    {
        return array_keys($this->config->get('bank.banks', []));
    }
}
